package com.hknc.btscale.utils;

import android.bluetooth.BluetoothDevice;
import android.util.Log;

import androidx.annotation.NonNull;

import java.nio.charset.Charset;
import java.util.List;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.unit.DataUnit;
import cn.hutool.core.util.CharsetUtil;
import cn.wandersnail.bluetooth.BTManager;
import cn.wandersnail.bluetooth.WriteCallback;

public class BTSendDataUtils {
    private static byte[] mBytes;
    static String[] time;

    public static void sendIsConnectBle() {

    }

    /**
     * 下发plu商品信息
     *
     * @param device
     * @param plu
     * @param price
     * @param name
     */
    public static void sendPluData(BluetoothDevice device, String plu, int price, String name, int priceLimit, String indexNo, String unit) {
        if (device==null) {
            return;
        }
        //下传商品信息（商户屏发起）（商品编号3字节）
        //指令返回0xEF
        byte[] byteEE = new byte[208];

        byteEE[0] = (byte) 0xFF;//帧开始
        byteEE[1] = (byte) 0xD1;//帧长度
        byteEE[2] = (byte) 0xEE;//命令
        byteEE[3] = (byte) 0x01;//商品数量

        //商品编号plu 3字节
        int pluNum = Integer.parseInt(plu);
        byte[] bytesPlu = DataConvertUtils.intToBytes2(pluNum);
        byteEE[4] = bytesPlu[0];
        byteEE[5] = bytesPlu[1];
        byteEE[6] = bytesPlu[2];

        //商品货号 3个字节
        byteEE[7] = (byte) 0x00;
        byteEE[8] = (byte) 0x00;
        byteEE[9] = (byte) 0x00;

        //商品索引码18个字节
//        byte[] bytesIndexNo = Convert.hexToBytes(Convert.toHex(indexNo, CharsetUtil.CHARSET_GBK));
//        for (int i = 10; i < 28; i++) {
//            byteEE[i] = bytesIndexNo[i - 10];
//        }
        //  13位纯数字索引码
//        for (int i = 0; i < indexNo.length(); i++) {
//            byteEE[i + 10] = Byte.parseByte(indexNo.substring(i, i + 1));
//        }

        String strIndexNo = indexNo + "\0\0\0\0\0";
        byte[] bytesIndexNo = strIndexNo.getBytes();

        for (int i = 10; i < 28; i++) {
            byteEE[i] = bytesIndexNo[i - 10];
        }
//        for (int i = 23; i < 28; i++) {
//            byteEE[i] = 0x30;
//        }

        //商品价格3个字节
        byte[] bytesPrice = DataConvertUtils.intToBytes2(price);
        byteEE[28] = bytesPrice[0];
        byteEE[29] = bytesPrice[1];
        byteEE[30] = bytesPrice[2];

        //商品名称20个字节
        String str = Convert.toHex(name, CharsetUtil.CHARSET_GBK);
        byte[] bytesName = Convert.hexToBytes(str);
        int diff = 20 - bytesName.length;

        for (int i = 0; i < bytesName.length; i++) {
            byteEE[i + 31] = bytesName[i];
        }

        byte[] bytes2 = new byte[diff];
        for (int i = 0; i < bytes2.length; i++) {
            bytes2[i] = 0x00;
        }
        //假如diff=4；  [0，16)   直到byteEE[50]
        for (int i = 0; i < 20 - diff; i++) {
            byteEE[bytesName.length + 30 + 1] = bytes2[0];
        }

        //商品单位1个字节
        byteEE[51] = Byte.parseByte(unit);

        //商品最高限价3个字节，值为0时，关闭本条plu限价功能
        byte[] bytesLimit = DataConvertUtils.intToBytes2(priceLimit);
        byteEE[52] = bytesLimit[0];
        byteEE[53] = bytesLimit[1];
        byteEE[54] = bytesLimit[2];
        Log.e("TAG", "sendPluData: " + byteEE[52] + "===" + byteEE[53] + "===" + byteEE[54]);
        byte[] temp = new byte[1];
        temp[0] = getXor(byteEE);
        byte[] source = addBytes(byteEE, temp);
        if (source == null)
            return;
        BTManager.getInstance().getConnection(device)
                .write("下传PLU", source, new WriteCallback() {
                    @Override
                    public void onWrite(@NonNull BluetoothDevice device, @NonNull String tag, @NonNull byte[] value, boolean result) {
                        Log.e("下传PLU:", DataConvertUtils.bytesToString(value));
                    }
                });
        Log.e("发送plu: ", DataConvertUtils.bytesToString(source));
    }

    /**
     * 下发小票信息/文本参数
     *
     * @param device
     * @param content
     * @param num
     */
    public static void sendTicket(BluetoothDevice device, String content, byte num) {
        if (device==null) {
            return;
        }
        byte[] byteC7 = new byte[194];
        byteC7[0] = (byte) 0xFF;
        byteC7[1] = (byte) 0xC3;
        byteC7[2] = (byte) 0xC6;
        //文本参数编号
        byteC7[3] = num;

        if (content == null || content.equals("")) {
            content = "无消息";
        }
        String str = Convert.toHex(content, CharsetUtil.CHARSET_GBK);
        byte[] bytesContent = Convert.hexToBytes(str);
        System.arraycopy(bytesContent, 0, byteC7, 4, bytesContent.length);
        byte[] temp = new byte[1];
        temp[0] = getXor(byteC7);
        byte[] source = addBytes(byteC7, temp);
        if (source == null)
            return;
        BTManager.getInstance().getConnection(device)
                .write("下传文本参数", source, new WriteCallback() {
                    @Override
                    public void onWrite(@NonNull BluetoothDevice device, @NonNull String tag, @NonNull byte[] value, boolean result) {
                        Log.e("TAG", "onWrite: " + DataConvertUtils.bytesToString(value));
                    }
                });
    }

    /**
     * 下发其他指令
     *
     * @param device
     * @param type
     */
    public static void sendData(BluetoothDevice device, int type) {
        if (device==null){
            return;
        }
        String s = TimeUtils.get_Time();
        time = s.split("/");
        switch (type) {
            //开秤协议：
            case 0xA0:
                byte[] temp = new byte[7];
                temp = new byte[7];
                temp[0] = (byte) 0xff;
                temp[1] = 0x08;
                temp[2] = (byte) 0xa0;
                temp[3] = (byte) 0xff;
                temp[4] = (byte) 0xff;
                temp[5] = (byte) 0xff;
                temp[6] = (byte) 0xff;

                byte bytes[] = new byte[1];
                bytes[0] = getXor(temp);

                mBytes = addBytes(temp, bytes);
                break;
            //锁秤协议：
            case 0xA1:
                byte[] temp1 = new byte[7];
                temp1 = new byte[7];
                temp1[0] = (byte) 0xff;
                temp1[1] = 0x08;
                temp1[2] = (byte) 0xa1;
                temp1[3] = (byte) 0xff;
                temp1[4] = (byte) 0xff;
                temp1[5] = (byte) 0xff;
                temp1[6] = (byte) 0xff;

                byte bytes1[] = new byte[1];
                bytes1[0] = getXor(temp1);

                mBytes = addBytes(temp1, bytes1);
                break;
            //双向通信测试（心跳测试）（电子秤发起，销售状
            //态下，间隔 5 秒发送一次同步数据）（无声音提示）
            //指令返回0xA3
            case 0xA2:

                break;

            case 0xA3:
                byte[] byteA3 = new byte[]{(byte) 0xFF, (byte) 0x04, (byte) 0xA3, (byte) 0x58};
                mBytes = byteA3;
                break;
            //电子秤清空秤上 PLU（由于秤上 PLU 数据量比较大，
            //需要给秤预留 18 秒以上的擦除时间，即：商户屏要
            //在收到秤的应答命令 18 秒之后方可继续下发数据）
            //指令返回0xA7
            case 0xA6:
                byte[] bytesA6 = new byte[4];
                bytesA6[0] = (byte) 0xFF;
                bytesA6[1] = (byte) 0x04;
                bytesA6[2] = (byte) 0xA6;
                bytesA6[3] = (byte) 0x5D;
                mBytes = bytesA6;
                break;
            //下发批次(商户屏发起)
            //指令返回0xC1
            case 0xC0:
                break;
            //抽检信息（电子秤发起）
//            case 0xC2:
//                mBytes = new byte[4];
//                mBytes[0] = (byte) 0xFF;
//                mBytes[1] = (byte) 0xc4;
//                mBytes[2] = (byte) 0xc2;
//                mBytes[3] = 0x39;
//                break;
            //商户屏下发命令：FF 0B C4 07 E1 06 1E 09 30 18 EF,下发时间设置命令
            case 0xC4:
                mBytes = setTime(time[0], time[1], time[2], time[3], time[4], time[5]);
                break;
            //文本参数下发（商户屏发起）
            //指令返回0xC7
            case 0xC6:
                break;
            //系统参数查询（商户屏发起）
            //指令返回0xC9
            case 0xC8:
                byte[] bytesC8 = new byte[6];
                bytesC8[0] = (byte) 0xFF;
                bytesC8[1] = (byte) 0x06;
                bytesC8[2] = (byte) 0xC8;
                bytesC8[3] = (byte) 0xFF;
                bytesC8[4] = (byte) 0xFF;
                bytesC8[5] = (byte) 0xFF;

                break;
            //系统参数设置（商户屏发起）
            //指令返回0XCB
            case 0xCA:
                byte[] byteCA = new byte[9];
                byteCA[0] = (byte) 0xFF;
                byteCA[1] = (byte) 0x0A;
                byteCA[2] = (byte) 0xCA;
                //参数编号
                byteCA[3] = (byte) 0x00;
                byteCA[4] = (byte) 0x11;
                //参数值
                byteCA[5] = (byte) 0x00;
                byteCA[6] = (byte) 0x00;
                byteCA[7] = (byte) 0x00;
                byteCA[8] = (byte) 0x01;
                byte[] tempCA = new byte[1];
                tempCA[0] = getXor(byteCA);
                mBytes = addBytes(byteCA, tempCA);
                break;
        }
        if (mBytes == null)
            return;
        BTManager.getInstance().getConnection(device)
                .write(type + "", mBytes, new WriteCallback() {
                    @Override
                    public void onWrite(@NonNull BluetoothDevice device, @NonNull String tag, @NonNull byte[] value, boolean result) {

                    }
                });
    }

    /**
     * 离线数据屏回复
     *
     * @param device
     * @param bytes
     */
    public static void sendOffBleReply(BluetoothDevice device, byte[] bytes) {
        if (device==null) {
            return;
        }
        byte[] byteBF = new byte[15];
        byteBF[0] = (byte) 0xFF;
        byteBF[1] = (byte) 0x10;
        byteBF[2] = (byte) 0xBF;
        for (int i = 0; i < bytes.length; i++) {
            byteBF[i + 3] = bytes[i];
        }
        byte[] tempBF = new byte[1];
        tempBF[0] = getXor(byteBF);

        mBytes = addBytes(byteBF, tempBF);
        String sendData = DataConvertUtils.bytesToString(mBytes);
        Log.e("TAG", "onWrite: 0xBF=============>" + sendData);
        if (mBytes == null)
            return;
        BTManager.getInstance().getConnection(device)
                .write("0xBF", mBytes, new WriteCallback() {
                    @Override
                    public void onWrite(@NonNull BluetoothDevice device, @NonNull String tag, @NonNull byte[] value, boolean result) {
                        String sendData = DataConvertUtils.bytesToString(value);
                        Log.e("TAG", "onWrite: 0xBF=============>" + sendData);
                    }
                });
    }

    /**
     * 屏回传收到异常信息
     *
     * @param device
     * @param bytes
     */
    public static void sendAbnormalBleReply(BluetoothDevice device, byte[] bytes) {
        byte[] byteBF = new byte[15];
        byteBF[0] = (byte) 0xFF;
        byteBF[1] = (byte) 0x10;
        byteBF[2] = (byte) 0xBF;
        for (int i = 0; i < bytes.length; i++) {
            byteBF[i + 3] = bytes[i];
        }
        byte[] tempBF = new byte[1];
        tempBF[0] = getXor(byteBF);

        mBytes = addBytes(byteBF, tempBF);
        String sendData = DataConvertUtils.bytesToString(mBytes);
        Log.e("TAG", "onWrite: 0xBF=============>" + sendData);
        if (mBytes == null)
            return;
        BTManager.getInstance().getConnection(device)
                .write("0xBF", mBytes, new WriteCallback() {
                    @Override
                    public void onWrite(@NonNull BluetoothDevice device, @NonNull String tag, @NonNull byte[] value, boolean result) {
                        String sendData = DataConvertUtils.bytesToString(value);
                        Log.e("TAG", "onWrite: 0xBF=============>" + sendData);
                    }
                });
    }

    /**
     * 下发系统参数设置
     */
    public static void sendSysConfig(BluetoothDevice device, int sysNum, int sysValue) {
        if (device==null) {
            return;
        }
        byte[] byteCA = new byte[9];
        byteCA[0] = (byte) 0xFF;
        byteCA[1] = (byte) 0x0A;
        byteCA[2] = (byte) 0xCA;

        //参数编号 0~499
        byte[] byteSysNum = DataConvertUtils.intTo2Bytes(sysNum);

        byteCA[3] = byteSysNum[0];
        byteCA[4] = byteSysNum[1];
        //参数值
        byte[] byteSysValue = DataConvertUtils.intTo4Bytes(sysValue);
        byteCA[5] = byteSysValue[0];
        byteCA[6] = byteSysValue[1];
        byteCA[7] = byteSysValue[2];
        byteCA[8] = byteSysValue[3];

        byte[] tempCA = new byte[1];
        tempCA[0] = getXor(byteCA);
        mBytes = addBytes(byteCA, tempCA);

        if (mBytes == null)
            return;
        BTManager.getInstance().getConnection(device)
                .write("0xCA", mBytes, new WriteCallback() {
                    @Override
                    public void onWrite(@NonNull BluetoothDevice device, @NonNull String tag, @NonNull byte[] value, boolean result) {

                    }
                });
    }

    /**
     * 交易上传成功屏回复
     *
     * @param bluetoothDevice
     * @param bytes
     */
    public static void sendUploadSuccess(BluetoothDevice bluetoothDevice, byte[] bytes) {
        if (bluetoothDevice==null) {
            return;
        }
        byte[] bytesB7 = new byte[15];
        bytesB7[0] = (byte) 0xFF;
        bytesB7[1] = (byte) 0x10;
        bytesB7[2] = (byte) 0xB7;
        for (int i = 0; i < bytes.length; i++) {
            bytesB7[i + 3] = bytes[i];
        }
        byte[] tempB7 = new byte[1];
        tempB7[0] = getXor(bytesB7);

        mBytes = addBytes(bytesB7, tempB7);

        Log.e("TAG", "sendUploadSuccess: =============>" + DataConvertUtils.bytesToString(mBytes));
        if (mBytes == null)
            return;
        BTManager.getInstance().getConnection(bluetoothDevice)
                .write("0xB7", mBytes, new WriteCallback() {
                    @Override
                    public void onWrite(@NonNull BluetoothDevice device, @NonNull String tag, @NonNull byte[] value, boolean result) {

                    }
                });
    }

    public static void sendUploadErrorSuccess(BluetoothDevice bluetoothDevice, byte[] bytes) {
        if (bluetoothDevice==null){
            return;
        }
        byte[] bytesB7 = new byte[15];
        bytesB7[0] = (byte) 0xFF;
        bytesB7[1] = (byte) 0x10;
        bytesB7[2] = (byte) 0xED;
        for (int i = 0; i < bytes.length; i++) {
            bytesB7[i + 3] = bytes[i];
        }
        byte[] tempB7 = new byte[1];
        tempB7[0] = getXor(bytesB7);

        mBytes = addBytes(bytesB7, tempB7);

        Log.e("TAG", "sendUploadErrorSuccess: =============>" + DataConvertUtils.bytesToString(mBytes));
        if (mBytes == null)
            return;
        BTManager.getInstance().getConnection(bluetoothDevice)
                .write("0xED", mBytes, new WriteCallback() {
                    @Override
                    public void onWrite(@NonNull BluetoothDevice device, @NonNull String tag, @NonNull byte[] value, boolean result) {

                    }
                });
    }

    public static void getSysConfig(BluetoothDevice device, int sysNum) {
        if (device==null){
            return;
        }
        byte[] byteC8 = new byte[5];
        byteC8[0] = (byte) 0xFF;
        byteC8[1] = (byte) 0x06;
        byteC8[2] = (byte) 0xC8;

        //系统参数编号0~499
        byte[] byteSysNum = DataConvertUtils.intTo2Bytes(sysNum);
        byteC8[3] = byteSysNum[0];
        byteC8[4] = byteSysNum[1];

        byte[] tempC8 = new byte[1];
        tempC8[0] = getXor(byteC8);
        mBytes = addBytes(byteC8, tempC8);
        if (mBytes == null)
            return;
        BTManager.getInstance().getConnection(device)
                .write("0xC8", mBytes, new WriteCallback() {
                    @Override
                    public void onWrite(@NonNull BluetoothDevice device, @NonNull String tag, @NonNull byte[] value, boolean result) {

                    }
                });
    }

    /******
     * auto yefang
     * 开称
     * **/
    public static byte[] open_balance() {
        byte a[] = {(byte) 0xFF, (byte) 0x08, (byte) 0xA0, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,};//
        byte b6[] = new byte[1];
        b6[0] = getXor(a);
        byte b7[] = addBytes(a, b6);
        return b7;
    }

    /*
     * auto yefang
     * 设置时间
     *
     **/
    public static byte[] setTime(String year, String mouth, String day, String hour, String minute, String second) {
        //Log.i("Integer.toHexString(Integer.parseInt(year) ",numToHex16(Integer.parseInt(year)).substring(2,6));
        byte b0[] = new byte[]{(byte) 0xff, (byte) 0x0b, (byte) 0xc4};
        //byte b0[]=new byte[]{(byte)0xff,(byte)0x0b,(byte)0x32};
        byte b_year[] = hexString2Bytes(numToHex16(Integer.parseInt(year)).substring(2, 6));//;0x07,(byte)0xe2
        byte bb[] = addBytes(b0, b_year);
        byte b_mouth[] = hexString2Bytes(numToHex16(Integer.parseInt(mouth)).substring(4, 6));
        byte b1[] = addBytes(bb, b_mouth);
        byte b_day[] = hexString2Bytes(numToHex16(Integer.parseInt(day)).substring(4, 6));
        byte b2[] = addBytes(b1, b_day);
        byte b_hour[] = hexString2Bytes(numToHex16(Integer.parseInt(hour)).substring(4, 6));
        byte b3[] = addBytes(b2, b_hour);
        byte b_minute[] = hexString2Bytes(numToHex16(Integer.parseInt(minute)).substring(4, 6));
        byte b4[] = addBytes(b3, b_minute);
        byte b_second[] = hexString2Bytes(numToHex16(Integer.parseInt(second)).substring(4, 6));
        byte b5[] = addBytes(b4, b_second);

        byte b6[] = new byte[1];
        b6[0] = getXor(b5);

        byte b7[] = addBytes(b5, b6);
        //String hex = Integer.toHexString(Integer.parseInt(year));
        for (int i1 = 0; i1 < b7.length; i1++) {
            //Log.i("b_year： "+i1+" ", b7[i1]+"");
        }
        return b7;
    }

    //前面的帧数据和最后以为数据进行相加和为0，即为一条完整数据
    public static byte getXor1(List<Byte> datas) {
        byte temp = datas.get(0);
        for (int i = 1; i < datas.size(); i++) {
            temp ^= datas.get(i);
        }
        return temp;
    }

    public static byte getXor(byte[] datas) {
        byte temp = datas[0];
        for (int i = 1; i < datas.length; i++) {
            temp ^= datas[i];
        }
        return temp;
    }

    /*
     * 16进制字符串转字节数组
     */
    public static byte[] hexString2Bytes(String hex) {

        if ((hex == null) || (hex.equals(""))) {
            return null;
        } else if (hex.length() % 2 != 0) {
            return null;
        } else {
            hex = hex.toUpperCase();
            int len = hex.length() / 2;
            byte[] b = new byte[len];
            char[] hc = hex.toCharArray();
            for (int i = 0; i < len; i++) {
                int p = 2 * i;
                b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1]));
            }
            return b;
        }

    }


    /*
     * 字符转换为字节
     */
    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    /**
     * @param data1
     * @param data2
     * @return data1 与 data2拼接的结果
     */
    public static byte[] addBytes(byte[] data1, byte[] data2) {
        byte[] data3 = new byte[data1.length + data2.length];
        System.arraycopy(data1, 0, data3, 0, data1.length);
        System.arraycopy(data2, 0, data3, data1.length, data2.length);
        return data3;
    }

    /**
     * 单个byte拼接到byte数组
     *
     * @param bytes
     * @param b
     * @return
     */
    public static byte[] addBytesSingle(byte[] bytes, byte b) {
        byte[] tempBytes = new byte[bytes.length + 1];
        System.arraycopy(bytes, 0, tempBytes, 0, bytes.length);
        tempBytes[bytes.length] = b;
        return tempBytes;
    }

    public static int[] addSingleInt(int[] a, int b) {
        int[] tempInts = new int[a.length + 1];
        System.arraycopy(a, 0, tempInts, 0, a.length);
        tempInts[a.length] = b;
        return tempInts;
    }

    //需要使用2字节表示b
    public static String numToHex16(int b) {
        System.out.println(String.format("%06x", b));
        return String.format("%06x", b);
    }

    public static String bytesToString(byte[] byteTemp) {
        char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
        // 一个字节对应两个16进制数，所以长度为字节数组乘2
        char[] resultCharArray = new char[byteTemp.length * 2];
        int index = 0;
        for (byte b : byteTemp) {
            resultCharArray[index++] = hexDigits[b >>> 4 & 0xf];
            resultCharArray[index++] = hexDigits[b & 0xf];
        }
        String result = new String(resultCharArray);
        return result;
    }

    private static byte toWeight(String unit) {
        byte weight = (byte) 0xFF;
        switch (unit) {
            case "Weight":
                weight = 1;
                break;
            case "件":
                weight = 2;
                break;
            case "kg":
                weight = 3;
                break;
            case "g":
                weight = 4;
                break;
            case "ton":
                weight = 5;
                break;
            case "lb":
                weight = 6;
                break;
            case "斤":
                weight = 7;
                break;
            case "100g":
                weight = 8;
                break;
            case "只":
                weight = 20;
                break;
            case "盒":
                weight = 21;
                break;
            case "包":
                weight = 22;
                break;
            case "箱":
                weight = 23;
                break;
            case "片":
                weight = 24;
                break;
            case "份":
                weight = 25;
                break;
            case "叠":
                weight = 26;
                break;
            case "块":
                weight = 27;
                break;
            case "套":
                weight = 28;
                break;
            case "组":
                weight = 29;
                break;
            case "个":
                weight = 30;
                break;
            case "条":
                weight = 31;
                break;
            case "瓶":
                weight = 32;
                break;
            default:
                weight = (byte) 0xFF;
                break;
        }
        return weight;
    }


}
